package com.ruoyi.system.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.system.api.domain.SysLeaveRequest;
import com.ruoyi.system.api.domain.SysLeaveRequestDetail;
import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.mapper.SysLeaveRequestDetailMapper;
import com.ruoyi.system.mapper.UserMapper;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.SysLeaveRequestMapper;
import com.ruoyi.system.service.ISysLeaveRequestService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

/**
 * 【请假申请】Service业务层处理
 * 
 * @author ruoyi
 * @date 2024-07-20
 */
@Service
public class SysLeaveRequestServiceImpl extends ServiceImpl<SysLeaveRequestMapper, SysLeaveRequest> implements ISysLeaveRequestService {
    @Autowired
    private SysLeaveRequestDetailMapper sysLeaveRequestDetailMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private HistoryService historyService;

    /**
     * 查询【请假申请】
     * 
     * @param requestId 【请假申请】主键
     * @return 【请假申请】
     */
    @Override
    public SysLeaveRequest selectSysLeaveRequestByRequestId(Long requestId) {
        return baseMapper.selectSysLeaveRequestByRequestId(requestId);
    }

    /**
     * 查询【请假申请】列表
     * 
     * @param sysLeaveRequest 【请假申请】
     * @return 【请假申请】
     */
    @Override
    public List<SysLeaveRequest> selectSysLeaveRequestList(SysLeaveRequest sysLeaveRequest) {
        LambdaQueryWrapper<SysLeaveRequest> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.isNotBlank(sysLeaveRequest.getRequestTitle()),SysLeaveRequest::getRequestTitle,sysLeaveRequest.getRequestTitle())
                .eq(ObjectUtils.isNotEmpty(sysLeaveRequest.getLeaveId()),SysLeaveRequest::getLeaveId,sysLeaveRequest.getLeaveId())
                .eq(StringUtils.isNotBlank(sysLeaveRequest.getStatus()),SysLeaveRequest::getStatus,sysLeaveRequest.getStatus())
                .eq(SysLeaveRequest::getLeaveId,SecurityUtils.getUserId());
        //testActivity();
        return baseMapper.selectList(wrapper);
    }

    public void testActivity(){
        //使用RepositoryService进行部署
        Deployment builder = repositoryService.createDeployment()
                .addClasspathResource("processes/leaveRequest.bpmn20.xml")
                .addClasspathResource("processes/leaveRequest.png")
                .tenantId("leaveRequest")//区分同一个流程所属系统，该值主要用于记录启动的流程实例归属于哪个系统。
                .name("请假审批工作流")
                .deploy();
        //输出部署信息
        System.out.println("流程部署id：" + builder.getId());
        System.out.println("流程部署名称：" + builder.getName());
    }

    /**
     * 新增【请假申请】
     * 
     * @param sysLeaveRequest 【请假申请】
     * @return 结果
     */
    @Override
    @Transactional
    public Boolean insertSysLeaveRequest(SysLeaveRequest sysLeaveRequest) {
        sysLeaveRequest.setCreateBy(SecurityUtils.getUsername());
        sysLeaveRequest.setCreateTime(DateUtils.getNowDate());
        HashMap<String, Object> map = new HashMap<>();
        sysLeaveRequest.setLeaveId(SecurityUtils.getUserId());
        map.put("leaveId", SecurityUtils.getUserId());
        boolean save = this.save(sysLeaveRequest);
        ProcessInstance instance = runtimeService.startProcessInstanceByKey("leaveRequest",sysLeaveRequest.getRequestId().toString(),map);
        System.out.println("流程定义的id = " + instance.getProcessDefinitionId());
        System.out.println("流程实例的id = " + instance.getId());
        sysLeaveRequest.setProcInstId(instance.getId());
        baseMapper.updateById(sysLeaveRequest);
        return save;
    }

    /**
     * 修改【请假申请】
     * 
     * @param sysLeaveRequest 【请假申请】
     * @return 结果
     */
    @Override
    public int updateSysLeaveRequest(SysLeaveRequest sysLeaveRequest) {
        return baseMapper.updateById(sysLeaveRequest);
    }

    /**
     * 批量删除【请假申请】
     * 
     * @param requestIds 需要删除的【请假申请】主键
     * @return 结果
     */
    @Override
    public int deleteSysLeaveRequestByRequestIds(Long[] requestIds) {
        return baseMapper.deleteBatchIds(Arrays.asList(requestIds));
    }

    /**
     * 删除【请假申请】信息
     * 
     * @param requestId 【请假申请】主键
     * @return 结果
     */
    @Override
    public int deleteSysLeaveRequestByRequestId(Long requestId) {
        return baseMapper.deleteById(requestId);
    }

    @Override
    @Transactional
    public int goCheck(Long requestId,String status) {
        //获取审核明细
        List<SysLeaveRequestDetail> sysLeaveRequestDetails = sysLeaveRequestDetailMapper.selectList(Wrappers.<SysLeaveRequestDetail>lambdaQuery().eq(SysLeaveRequestDetail::getRequestId, requestId).orderByDesc(SysLeaveRequestDetail::getDetailId));
        //获取当前登录人
        Long userId = SecurityUtils.getUserId();
        //获取当前请假信息
        SysLeaveRequest sysLeaveRequest = baseMapper.selectOne(Wrappers.<SysLeaveRequest>lambdaQuery().eq(SysLeaveRequest::getRequestId, requestId));
        //获取任务实例id
        String procInstId = sysLeaveRequest.getProcInstId();
        //获取当前登录用户部门
        Long deptId = userMapper.selectOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUserId,userId)).getDeptId();
        //获取当前登录用户上级岗位id
        Long approverPost = baseMapper.getapproverPostId(sysLeaveRequest.getPostId());
        //如果审核过则获取上次审核人的岗位Id
        if (!CollectionUtils.isEmpty(sysLeaveRequestDetails)){
            approverPost = baseMapper.getapproverPostId(sysLeaveRequestDetails.get(0).getApproverPost());
        }
        //获取用户上级岗位用户id
        Long postUserId = baseMapper.getPostUserId(deptId,approverPost);
        System.err.println("岗位上级领导用户id"+postUserId+"@@@@@@");
        HashMap<String, Object> map = new HashMap<>();
        map.put("postUserId",postUserId);
        map.put("days",4);
        if (status.equals("3")){
            map.put("falg",1);
        }else {
            map.put("falg",0);
        }
        Task task = taskService.createTaskQuery().processInstanceId(procInstId).taskAssignee(userId.toString()).singleResult();
        taskService.complete(task.getId(),map);
        HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(procInstId).singleResult();
        //修改请假请求信息状态
        SysLeaveRequest updateSysLeaveRequest = new SysLeaveRequest();
        updateSysLeaveRequest.setRequestId(requestId);
        //请假审核明细
        SysLeaveRequestDetail sysLeaveRequestDetail = new SysLeaveRequestDetail();
        sysLeaveRequestDetail.setRequestId(requestId);
        sysLeaveRequestDetail.setApproverId(userId);
        sysLeaveRequestDetail.setApproverPost(approverPost);
        sysLeaveRequestDetail.setStatus(status);
        sysLeaveRequestDetail.setCreateTime(new Date());
        if (status.equals("3")){                            //判断是否是驳回操作
            updateSysLeaveRequest.setStatus(status);
            sysLeaveRequestDetail.setApprovalOpinion("请假驳回");
        }else {
            if (historicProcessInstance.getEndTime()!=null){ //判断是否是最后一人审核
                updateSysLeaveRequest.setStatus("2");
            }else {
                updateSysLeaveRequest.setStatus("1");
            }
            sysLeaveRequestDetail.setApprovalOpinion("好好休息");
        }
        int i = baseMapper.updateById(updateSysLeaveRequest);
        sysLeaveRequestDetailMapper.insert(sysLeaveRequestDetail);
        return i;
    }

    @Override
    public List<SysLeaveRequest> leaveWaitCheck() {
        //获取任务集合
        List<Task> taskList = taskService.createTaskQuery()
                .processDefinitionKey("leaveRequest")
                .taskAssignee(SecurityUtils.getUserId().toString())
                .list();
        if (!CollectionUtils.isEmpty(taskList)){
            List<String> ProcessInstanceIds = taskList.stream().map(TaskInfo::getProcessInstanceId).collect(Collectors.toList());
            return baseMapper.selectList(Wrappers.<SysLeaveRequest>lambdaQuery().in(SysLeaveRequest::getProcInstId, ProcessInstanceIds));
        }
        return new ArrayList<>();
    }

    @Override
    public List<Map<String, Objects>> selectApprover() {
        Long userId = SecurityUtils.getUserId();
        return null;
    }
}
